//
//  RdbPanGestureController.swift
//  rdb-led-banner
//
//  Created by radiobox3 on 2025/4/22.
//

import UIKit


class RdbPanGestureController: BaseViewController {
    
    var orginFrame: CGRect = CGRect.zero
    
    var lastTouchPoint: CGPoint = CGPoint.zero
    
    var lastVelocity: CGFloat = 0
    
    var shouldDismiss: Bool = false
    
    var closeAction: (() -> Void)?
    
    var canGesture: Bool = true{
        didSet{
            if canGesture{
                bottomLayer.addTarget(self, action: #selector(bottomLayerAction), for: .touchUpInside)
                topIndicatorView.isHidden = false
                swipeGesture.require(toFail: self.panGesture)
                contentView.addGestureRecognizer(self.panGesture)
                contentView.addGestureRecognizer(self.swipeGesture)
                closeButton.isHidden = true
            }else{
                bottomLayer.removeTarget(self, action: #selector(bottomLayerAction), for: .touchUpInside)
                topIndicatorView.isHidden = true
                contentView.removeGestureRecognizer(self.panGesture)
                contentView.removeGestureRecognizer(self.swipeGesture)
                showCloseButton()
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.clear
        self.view.addSubview(self.bottomLayer)
        self.bottomLayer.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        self.contentView.addSubview(topIndicatorView)
        self.topIndicatorView.snp.makeConstraints{
            $0.centerX.equalToSuperview()
            $0.top.equalTo(10)
            $0.size.equalTo(CGSize(width: 70, height: 4))
        }
        self.view.addSubview(self.contentView)
        self.view.addSubview(closeButton)
        self.closeButton.snp.makeConstraints{
            $0.bottom.equalTo(contentView.snp.top)
            $0.trailing.equalTo(-16)
            $0.size.equalTo(24)
        }
    }
    
    lazy var bottomLayer: UIControl = {
        let bottomLayer = UIControl()
        return bottomLayer
    }()
    
    lazy var contentView: UIView = {
        let contentView = UIView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: UIDevice.screenWidth(), height: UIDevice.screenHeight())))
        contentView.layer.cornerRadius = 14
        return contentView
    }()
    private lazy var closeButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(named: "guide_close")?.withRenderingMode(.alwaysOriginal), for: .normal)
        button.addTarget(self, action: #selector(closeButtonAction), for: .touchUpInside)
        button.alpha = 0.0
        return button
    }()
    lazy var topIndicatorView: UIView = {
        let indicatorView = UIView()
        indicatorView.layer.cornerRadius = 2
        indicatorView.backgroundColor = UIColor("#666666")
        return indicatorView
    }()
    
    lazy var panGesture: UIPanGestureRecognizer = {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(pangestureAction))
        return panGesture
    }()
    
    lazy var swipeGesture: UISwipeGestureRecognizer = {
        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeGestureAction))
        swipeGesture.direction = .down
        return swipeGesture
    }()
    
    @objc func bottomLayerAction() {
        self.dismissView()
    }
    @objc func swipeGestureAction(_ gesture: UISwipeGestureRecognizer) {
        self.dismissView()
    }
    @objc func pangestureAction(_ gesture: UIPanGestureRecognizer) {
        
        let point = gesture.location(in: self.view)
        let velocity = gesture.velocity(in: self.contentView).y
        
        switch gesture.state {
        case .began:
            self.orginFrame = self.contentView.frame
        case .changed:
            let speed = point.y - self.lastTouchPoint.y
            var tempRect = self.contentView.frame
            tempRect.origin.y = tempRect.origin.y + speed
            if tempRect.origin.y > self.orginFrame.origin.y {
                self.contentView.frame = tempRect
            }
            self.shouldDismiss = (velocity >= self.lastVelocity) && velocity > 0
        default:
            self.finishTouched()
        }
        
        self.lastTouchPoint = point
        self.lastVelocity = velocity
    }
    @objc func closeButtonAction(){
        self.dismissView()
        self.closeAction?()
    }
    
    func finishTouched() {
        if (self.contentView.frame.origin.y - self.orginFrame.origin.y) >  self.orginFrame.size.height / 4 || self.shouldDismiss {
            self.dismissView()
        } else {
            UIView.animate(withDuration: 0.25) {
                self.contentView.frame = self.orginFrame
            }
        }
    }
    func dismissView () {
        UIView.animate(withDuration: 0.25) {
            self.contentView.frame = CGRect(origin: CGPoint(x: 0, y: UIDevice.screenHeight()), size: self.contentView.bounds.size)
        } completion: { finished in
            if finished {
                self.dismiss(animated: false)
            }
        }
    }
    func showCloseButton(){
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
            UIView.animate(withDuration: 0.3){
                self.closeButton.alpha = 0.6
            }
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIView.animate(withDuration: 0.25){
            self.contentView.frame = CGRect(origin: CGPoint(x: 0, y: -UIDevice.screenHeight()), size: self.contentView.bounds.size)
        }
    }
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.modalPresentationStyle = .overFullScreen
        self.modalTransitionStyle = .crossDissolve
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
